#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Filename: xmind_to_excel_ui.py
# Author: ChenChangSong
# Date: 2025-08-24

"""
功能描述: XMind→Excel 页面 UI。
"""
import sys
import os
import json
from pathlib import Path
from PyQt5.QtWidgets import (
    QFileDialog,
    QGridLayout,
    QHBoxLayout,
    QLabel,
    QLineEdit,
    QPushButton,
    QSpinBox,
    QVBoxLayout,
    QWidget,
    QMessageBox,
    QToolButton
)
from .common_ui import LogPanel, InfoWithImageDialog, get_project_root

# 定义配置文件路径，使用目录层级设置配置文件
CONFIG_PATH = get_project_root() / "files" / "config_file" / "dir_level_settings.json"
from function_code.xmind_to_excel.export_as_excel_order import export_to_excel_order
from function_code.xmind_to_excel.export_as_excel_reverse import export_to_excel_reverse

class XMindToExcelPage(QWidget):
    def __init__(self) -> None:
        super().__init__()
        self._init_ui()

    def _init_ui(self) -> None:
        root = QVBoxLayout(self)
        root.setSpacing(10)
        root.setContentsMargins(10, 10, 10, 10)

        # 添加说明标签和问号图标
        info_hbox = QHBoxLayout()
        info_hbox.setSpacing(5)
        
        # 说明标签
        info_label = QLabel("说明！此处的功能是将XMind脑图用例导出为Excel文件，然后TAPD手动选择Excel导入（API一键导入用：XMind→TAPD）。\n"
             "注意：1、目录层级尽量全部保留，方便以后直接从tapd导出为XMind脑图。2、脑图中的需求ID要7位的哦！")
        
        # 问号图标按钮 - 使用与login_ui类似的实现方式
        question_btn = self._help_btn()
        
        # 获取图片路径
        image_path = get_project_root() / "files" / "software_image_icon" / "需求ID_7位.png"
        
        # 设置悬浮提示和点击事件
        img_url = image_path.as_uri()
        title = "需求ID说明"
        text = "此处是通过API导入TAPD，注意需求ID要用7位的如图："
        
        # 悬浮直接展示与点击相同的图文内容
        html_tooltip = f"<b>{title}</b><br/>{text}<br/><img src='{img_url}' width='320'/>"
        question_btn.setToolTip(html_tooltip)
        
        # 点击弹窗
        question_btn.clicked.connect(lambda _=None, t=title, m=text, p=image_path: InfoWithImageDialog(t, m, p).exec_())
        
        info_hbox.addWidget(info_label)
        info_hbox.addWidget(question_btn)
        info_hbox.addStretch()  # 添加伸缩项使内容靠左
        root.addLayout(info_hbox)

        grid = QGridLayout()
        grid.setHorizontalSpacing(5)
        grid.setVerticalSpacing(8)
        grid.setContentsMargins(5, 5, 5, 5)

        self.input_file = QLineEdit()
        self.input_file.setReadOnly(True)
        self.input_file.setPlaceholderText("当前未选择XMind文件")
        self.input_file.setMinimumWidth(400)

        self.btn_choose = QPushButton("选择XMind文件")
        self.btn_choose.setMinimumSize(120, 30)
        self.btn_choose.setMaximumSize(180, 30)
        self.btn_choose.clicked.connect(self._choose_file)

        self.spin_level = QSpinBox()
        self.spin_level.setRange(3, 99)
        # 从配置文件读取保存的目录层级，如果没有则使用默认值99
        saved_level = self._get_saved_level()
        self.spin_level.setValue(saved_level)
        self.spin_level.setPrefix("保留 ")
        self.spin_level.setSuffix(" 级目录(Xmind目录层级低于此值则保留全部)")
        self.spin_level.setToolTip("只能输入大于等于3的整数")
        # 连接值改变信号，保存设置
        self.spin_level.valueChanged.connect(self._save_level_setting)

        self.btn_export_order = QPushButton("导出为Excel(正序)")
        self.btn_export_reverse = QPushButton("导出为Excel(倒序)")
        button_min_width = 120
        button_height = 30
        self.btn_export_order.setMinimumSize(button_min_width, button_height)
        self.btn_export_order.setMaximumSize(180, button_height)
        self.btn_export_reverse.setMinimumSize(button_min_width, button_height)
        self.btn_export_reverse.setMaximumSize(180, button_height)

        button_hbox = QHBoxLayout()
        button_hbox.setSpacing(5)
        button_hbox.addWidget(self.btn_export_order)
        button_hbox.addWidget(self.btn_export_reverse)

        grid.addWidget(self.btn_choose, 0, 0)
        grid.addWidget(self.input_file, 0, 1, 1, 2)
        grid.addWidget(QLabel("保留目录层级:"), 1, 0)
        grid.addWidget(self.spin_level, 1, 1)
        grid.addLayout(button_hbox, 1, 2)

        grid.setColumnMinimumWidth(0, 150)
        grid.setColumnStretch(1, 1)
        grid.setColumnStretch(2, 0)

        root.addLayout(grid)

        self.log_panel = LogPanel()
        root.addWidget(self.log_panel)

        # 连接按钮事件
        self.btn_export_order.clicked.connect(self._export_order)
        self.btn_export_reverse.clicked.connect(self._export_reverse)

    def _choose_file(self) -> None:
        # 清空屏幕日志
        self.log_panel.clear_screen_logs()
        path, _ = QFileDialog.getOpenFileName(
            self, "选择XMind文件", "", "XMind (*.xmind)")
        if path:
            self.input_file.setText(path)
            self.log_panel.append_log(f"已选择XMind文件: {path}")

    def _export_order(self) -> None:
        if not self.input_file.text():
            QMessageBox.warning(self, "提示", "请先选择XMind文件")
            return

        xmind_path = self.input_file.text()
        level = self.spin_level.value()

        try:
            files_list = export_to_excel_order(xmind_path, level)
            if files_list is None:  # 用户取消操作
                self.log_panel.append_log("用户取消导出操作")
                return
            if files_list:
                self.log_panel.append_log(f"成功导出Excel文件: {', '.join(files_list)}")
                QMessageBox.information(self, "成功", f"已成功导出{len(files_list)}个Excel文件")
            else:
                self.log_panel.append_log("导出Excel文件失败")
                QMessageBox.warning(self, "失败", "导出Excel文件失败")
        except Exception as e:
            self.log_panel.append_log(f"导出Excel文件时出错: {str(e)}")
            QMessageBox.critical(self, "错误", f"导出Excel文件时出错: {str(e)}")

    def _export_reverse(self) -> None:
        if not self.input_file.text():
            QMessageBox.warning(self, "提示", "请先选择XMind文件")
            return

        xmind_path = self.input_file.text()
        level = self.spin_level.value()

        try:
            files_list = export_to_excel_reverse(xmind_path, level)
            if files_list is None:  # 用户取消操作
                self.log_panel.append_log("用户取消导出操作")
                return
            if files_list:
                self.log_panel.append_log(f"成功导出Excel文件: {', '.join(files_list)}")
                QMessageBox.information(self, "成功", f"已成功导出{len(files_list)}个Excel文件")
            else:
                self.log_panel.append_log("导出Excel文件失败")
                QMessageBox.warning(self, "失败", "导出Excel文件失败")
        except Exception as e:
            self.log_panel.append_log(f"导出Excel文件时出错: {str(e)}")
            QMessageBox.critical(self, "错误", f"导出Excel文件时出错: {str(e)}")
            
    @staticmethod
    def _help_btn() -> QToolButton:
        """创建问号帮助按钮，与login_ui.py保持一致"""
        btn = QToolButton()
        btn.setText("❓")
        btn.setAutoRaise(True)
        btn.setToolTip("查看填写说明与示例图")
        return btn
    
    def _get_saved_level(self) -> int:
        """从配置文件读取保存的目录层级设置"""
        try:
            # 确保配置文件目录存在
            CONFIG_PATH.parent.mkdir(parents=True, exist_ok=True)
            
            # 如果配置文件存在，读取设置
            if CONFIG_PATH.exists():
                with open(CONFIG_PATH, 'r', encoding='utf-8') as f:
                    settings = json.load(f)
                    return settings.get('to_excel_dir_level', 99)
        except Exception:
            # 读取失败时使用默认值
            pass
        return 99
    
    def _save_level_setting(self, value: int) -> None:
        """保存目录层级设置到配置文件"""
        try:
            # 确保配置文件目录存在
            CONFIG_PATH.parent.mkdir(parents=True, exist_ok=True)
            
            # 读取现有设置
            settings = {}
            if CONFIG_PATH.exists():
                try:
                    with open(CONFIG_PATH, 'r', encoding='utf-8') as f:
                        settings = json.load(f)
                except Exception:
                    # 读取失败时使用空字典
                    pass
            
            # 更新设置
            settings['to_excel_dir_level'] = value
            
            # 保存设置
            with open(CONFIG_PATH, 'w', encoding='utf-8') as f:
                json.dump(settings, f, ensure_ascii=False, indent=2)
        except Exception:
            # 保存失败时静默处理，不影响用户使用
            pass